﻿namespace HynuIOTA.Web.Areas.Admin.Controllers
{
    using HynuIOTA.Common.Attribute;
    using HynuIOTA.Entity;
    using HynuIOTA.Entity.FormatEntity;
    using HynuIOTA.Web.Helpers;
    using HynuIOTA.Web.Models;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Web.Mvc;
    using static HynuIOTA.Common.StringConst;

    public class PermissionController : BaseController
    {
        #region Action
        #region Action - View
        /// <summary>
        /// GET: Admin/Permission/ActionList
        /// 动作列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult ActionList()
        {
            return View();
        }

        /// <summary>
        /// GET: Admin/Permission/AddAction
        /// 添加Action
        /// </summary>
        /// <returns></returns>
        public ActionResult AddAction()
        {
            return View();
        }

        /// <summary>
        /// GET: Admin/Permission/EditAction
        /// 编辑Action
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<ActionResult> EditAction(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsMsg(MODEL_VALIDATE_ERROR);
            }

            var action = await OpContext.Service.Action.Where(a => a.Id == Id.Value).FirstOrDefaultAsync();
            if (action == null)
            {
                return OpContext.JsMsg(DATA_NOEXIST_ERROR);
            }

            ViewBag.action = action;
            return View();
        }
        #endregion

        #region Action - API
        /// <summary>
        /// POST: /Admin/Permission/PostAction
        /// 添加Action
        /// </summary>
        /// <param name="actionViewModel"></param>
        /// <returns></returns>
        [HttpPost]
        [AjaxRequest]
        public async Task<ActionResult> PostAction(PostActionViewModel actionViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }
            var action = new HynuIOTA.Entity.Action()
            {
                Name = actionViewModel.Name,
                Description = actionViewModel.Description,
                Url = Url.Action(actionViewModel.rAction, actionViewModel.rController, new { area = actionViewModel.rArea }) ?? "*",
                rAction = actionViewModel.rAction.ToLower(),
                rController = actionViewModel.rController.ToLower(),
                rArea = actionViewModel.rArea.ToLower(),
                rMethod = actionViewModel.rMethod.ToLower()
            };
            OpContext.Service.Action.Add(action);
            var result = await OpContext.SaveChangesAsync();

            return result ?? OpContext.JsonMsgOK(DATA_ADD_SUCCESS);
        }

        /// <summary>
        /// 修改Action
        /// </summary>
        /// <param name="actionViewModel"></param>
        /// <returns></returns>
        [HttpPut]
        [AjaxRequest]
        public async Task<ActionResult> PutAction(PutActionViewModel actionViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATECODE_ERROR);
            }

            var actionFromDb = await OpContext.Service.Action.Where(a => a.Id == actionViewModel.Id).FirstOrDefaultAsync();
            if (actionFromDb == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            Tools.SetValues(actionFromDb, actionViewModel, ModelState.Keys.ToArray());
            var result = await OpContext.SaveChangesAsync();

            return result ?? OpContext.JsonMsgOK(DATA_MODIFY_SUCCESS);
        }

        /// <summary>
        /// DELETE: Admin/Permission/DeleteAction
        /// 删除Action
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpDelete]
        [AjaxRequest]
        public async Task<ActionResult> DeleteAction(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var action = await OpContext.Service.Action.Where(a => a.Id == Id.Value).FirstOrDefaultAsync();
            if (action == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            OpContext.Service.Action.Delete(action);
            var result = await OpContext.SaveChangesAsync();

            return result ?? OpContext.JsonMsgOK(DATA_DELECT_SUCCESS);
        }
        /// <summary>
        /// ANY: Admin/Permission/GetActionPage
        /// 获取动作列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <returns></returns>
        [AjaxRequest]
        public async Task<ActionResult> GetActionPage(int page = 1, int rows = int.MaxValue)
        {
            var pageData = new PageData() { PageIndex = page, PageSize = rows };
            var pageList =
                await (await OpContext.Service.Action.WherePageAsync(pageData, a => true, a => a.rArea, true))
                    .ToListAsync();

            return OpContext.JsonMsgOK(data: new { total = pageData.RowCount, rows = pageList.Select(a => a.ToPOCO()) });
        }
        #endregion
        #endregion

        #region Relo
        #region Relo - View

        /// <summary>
        /// GET: Admin/Permission/ReloList
        /// 权限列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult ReloList()
        {
            return View();
        }

        /// <summary>
        /// GET: Admin/Permission/AddRelo
        /// 添加Relo
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult AddRelo()
        {
            return View();
        }

        /// <summary>
        /// GET: Admin/Permission/EditRelo
        /// 编辑Relo
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult> EditRelo(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsMsg(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == Id.Value).FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsMsg(DATA_NOEXIST_ERROR);
            }

            ViewBag.relo = relo;
            return View();
        }

        /// <summary>
        /// GET: Admin/Permission/EditReloActionList
        /// 编辑权限动作列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult EditReloActionList(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsMsg(MODEL_VALIDATE_ERROR);
            }

            ViewBag.Id = Id.Value;
            return View();
        }

        /// <summary>
        /// GET: Admin/Permission/EditReloActionList
        /// 编辑权限用户列表
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult EditReloUserList(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsMsg(MODEL_VALIDATE_ERROR);
            }

            ViewBag.Id = Id.Value;
            return View();
        } 
        #endregion

        #region Relo - API
        /// <summary>
        /// ANY: Admin/Permission/GetReloPage
        /// 获取分页权限列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <returns></returns>
        [AjaxRequest]
        public async Task<ActionResult> GetReloPage(int page = 1, int rows = int.MaxValue)
        {
            var pageData = new PageData() { PageIndex = page, PageSize = rows };
            var pageList = await (await OpContext.Service.Relo.WherePageAsync(pageData, r => true, r => r.Id, true))
                    .Select(r => new { r.Id, r.Name, r.Description, UserCount = r.User.Count, ActionCount = r.Action.Count }).ToListAsync();

            return OpContext.JsonMsgOK(data: new { total = pageData.RowCount, rows = pageList });
        }

        /// <summary>
        /// ANY: Admin/Permission/GetReloAction
        /// 获取Relo的所有Action
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [AjaxRequest]
        public async Task<ActionResult> GetReloAction(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == Id.Value).Include(r => r.Action).FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            return OpContext.JsonMsgOK(data: relo.Action.Select(a => a.ToPOCO()));
        }

        /// <summary>
        /// ANY: Admin/Permission/GetReloUser
        /// 获取Relo的所有User
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [AjaxRequest]
        public async Task<ActionResult> GetReloUser(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == Id.Value).Include(r => r.User).FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            return OpContext.JsonMsgOK(data: relo.User.Select(u => u.ToPOCO()));
        }

        /// <summary>
        /// PUT: Admin/Permission/PutReloAction
        /// 更改ReloAction
        /// </summary>
        /// <param name="reloActionViewModel"></param>
        /// <returns></returns>
        [HttpPut]
        [AjaxRequest]
        public async Task<ActionResult> PutReloAction(PutReloActionViewModel reloActionViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == reloActionViewModel.ReloId)
                .FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            try
            {
                relo.Action.Clear();
                if (reloActionViewModel.ActionIds != null)
                {
                    var actions = await OpContext.Service.Action.Where(a => reloActionViewModel.ActionIds.Contains(a.Id))
                .ToArrayAsync();
                    foreach (var item in actions)
                    {
                        relo.Action.Add(item);
                    } 
                }
            }
            catch (Exception ex)
            {
                return OpContext.JsonMsgErr(ex.Message);
            }

            var result = await OpContext.SaveChangesAsync();
            return result ?? OpContext.JsonMsgOK(DATA_SAVECHANGES_SUCCESS);
        }

        /// <summary>
        /// PUT: Admin/Permission/PutReloUser
        /// 更改Relo User
        /// </summary>
        /// <param name="reloUserViewModel"></param>
        /// <returns></returns>
        [HttpPut]
        [AjaxRequest]
        public async Task<ActionResult> PutReloUser(PutReloUserViewModel reloUserViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == reloUserViewModel.ReloId)
                .FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            try
            {
                relo.User.Clear();
                if (reloUserViewModel.UserIds != null)
                {
                    var users = await OpContext.Service.User.Where(u => reloUserViewModel.UserIds.Contains(u.Id))
                        .ToArrayAsync();
                    foreach (var item in users)
                    {
                        relo.User.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                return OpContext.JsonMsgErr(ex.Message);
            }

            var result = await OpContext.SaveChangesAsync();
            return result ?? OpContext.JsonMsgOK(DATA_SAVECHANGES_SUCCESS);

        }

        /// <summary>
        /// Post Admin/Permission/PostRelo
        /// 添加Relo
        /// </summary>
        /// <param name="reloViewModel"></param>
        /// <returns></returns>
        [HttpPost]
        [AjaxRequest]
        public async Task<ActionResult> PostRelo(PostReloViewModel reloViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = new Relo()
            {
                Name = reloViewModel.Name,
                Description = reloViewModel.Description
            };
            OpContext.Service.Relo.Add(relo);
            var result = await OpContext.SaveChangesAsync();

            return result ?? OpContext.JsonMsgOK(DATA_ADD_SUCCESS);
        }

        /// <summary>
        /// DELETE: Admin/Permission/DeleteRelo
        /// 删除Relo
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpDelete]
        [AjaxRequest]
        public async Task<ActionResult> DeleteRelo(int? Id)
        {
            if (Id == null)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == Id.Value).FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            OpContext.Service.Relo.Delete(relo);
            var result = await OpContext.SaveChangesAsync();

            return result ?? OpContext.JsonMsgOK(DATA_DELECT_SUCCESS);
        }

        /// <summary>
        /// PUT: Admin/Permission/PutRelo
        /// 更改Relo 
        /// </summary>
        /// <param name="reloViewModel"></param>
        /// <returns></returns>
        public async Task<ActionResult> PutRelo(PutReloViewModel reloViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return OpContext.JsonMsgFail(MODEL_VALIDATE_ERROR);
            }

            var relo = await OpContext.Service.Relo.Where(r => r.Id == reloViewModel.Id).FirstOrDefaultAsync();
            if (relo == null)
            {
                return OpContext.JsonMsgFail(DATA_NOEXIST_ERROR);
            }

            Tools.SetValues(relo, reloViewModel, ModelState.Keys.ToArray());
            var result = await OpContext.SaveChangesAsync();

            return result ?? OpContext.JsonMsgOK(DATA_MODIFY_SUCCESS);
        }

        #endregion

        #endregion

        #region 获取菜单权限
        private static readonly List<EasyUITreeNode> AdminPerTree = new List<EasyUITreeNode>() {
            new EasyUITreeNode(){
                id = 0,
                text = "用户权限管理",
                children = new List<EasyUITreeNode>(){
                    new EasyUITreeNode(){
                        id = 100,
                        text = "用户列表",
                        attributes = new { url = "../Admin/User/UserList" }
                    },
                    new EasyUITreeNode()
                    {
                        id = 102,
                        text = "动作列表",
                        attributes = new {url = "../Admin/Permission/ActionList"}
                    },
                    new EasyUITreeNode(){
                        id = 105,
                        text = "权限组列表",
                        attributes = new { url = "../Admin/Permission/ReloList" }
                    }
                }
            },
            new EasyUITreeNode(){
                id = 5,
                text = "新闻通知管理",
                children = new List<EasyUITreeNode>(){
                    new EasyUITreeNode(){
                        id = 120,
                        text = "新闻列表",
                        attributes = new { url = "../Admin/News/NewsList" }
                    },
                    new EasyUITreeNode(){
                        id = 121,
                        text = "通知列表",
                        attributes = new { url = "../Admin/Notice/NoticeList" }
                    }
                }
            },
            new EasyUITreeNode(){
                id = 20,
                text = "博客文章管理",
                children = new List<EasyUITreeNode>(){
                    new EasyUITreeNode(){
                        id = 140,
                        text = "文章列表",
                        attributes = new { url = "../Admin/Article/ArticleList" }
                    }
                }
            },
            new EasyUITreeNode(){
                id = 25,
                text = "其它信息管理",
                children = new List<EasyUITreeNode>(){
                    new EasyUITreeNode(){
                        id = 160,
                        text = "栏目列表",
                        attributes = new { url = "../Admin/Channel/ChannelList" }
                    },
                    //new EasyUITreeNode(){
                    //    id = 165,
                    //    text = "友情链接列表",
                    //    attributes = new { url = "../LogRecord/ExceptionLogList" }
                    //},
                    new EasyUITreeNode(){
                        id = 170,
                        text = "网站全局管理",
                        attributes = new { url = "../Admin/Config/Index" }
                    },
                    new EasyUITreeNode(){
                        id = 165,
                        text = "清除网站缓存",
                        attributes = new { url = "../Admin/Config/ClearAllOutPutCache" }
                    }
                }
            }//,
            //new EasyUITreeNode(){
            //    id = 30,
            //    text = "日志管理",
            //    children = new List<EasyUITreeNode>(){
            //        new EasyUITreeNode(){
            //            id = 180,
            //            text = "异常日志",
            //            attributes = new { url = "../LogRecord/OperationLogList" }
            //        },
            //        new EasyUITreeNode(){
            //            id = 185,
            //            text = "运行日志",
            //            attributes = new { url = "../LogRecord/ExceptionLogList" }
            //        }
            //    }
            //}
        };

        /// <summary>
        /// ANY: Admin/Permission/GetPermissionTree
        /// 获取菜单权限
        /// </summary>
        /// <returns></returns>
        public ActionResult GetPermissionTree()
        {
            return OpContext.JsonMsgOK(data: AdminPerTree);
        }
        #endregion
    }
}